Fix make_page_readonly/make_page_writeable on PAE guests - previous behaviour
authorsmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>
Fri, 11 Nov 2005 18:02:49 +0000 (19:02 +0100)
committersmh22@firebug.cl.cam.ac.uk <smh22@firebug.cl.cam.ac.uk>
Fri, 11 Nov 2005 18:02:49 +0000 (19:02 +0100)
was incorrect when machine address > 4GB. We believe this fixes bugzilla #267.

Also tidy up and fix show_page_walk.

Signed-off-by: Steven Hand <steven@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/i386/mm/pgtable.c
xen/arch/x86/x86_32/traps.c

index 442ee8da14ab2cf6bbc2f259f92cec9f89691bd1..05987d5e3879df94c5443871a2c59d88674abd35 100644 (file)
@@ -398,14 +398,14 @@ void make_page_readonly(void *va)
 {
        pte_t *pte = virt_to_ptep(va);
        set_pte(pte, pte_wrprotect(*pte));
-       if ( (unsigned long)va >= (unsigned long)high_memory )
-       {
-               unsigned long phys;
-               phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+       if ((unsigned long)va >= (unsigned long)high_memory) {
+               unsigned long pfn; 
+               pfn = pte_pfn(*pte); 
 #ifdef CONFIG_HIGHMEM
-               if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+               if (pfn < highstart_pfn)
 #endif
-                       make_lowmem_page_readonly(phys_to_virt(phys));
+                       make_lowmem_page_readonly(
+                               phys_to_virt(pfn << PAGE_SHIFT)); 
        }
 }
 
@@ -413,21 +413,20 @@ void make_page_writable(void *va)
 {
        pte_t *pte = virt_to_ptep(va);
        set_pte(pte, pte_mkwrite(*pte));
-       if ( (unsigned long)va >= (unsigned long)high_memory )
-       {
-               unsigned long phys;
-               phys = machine_to_phys(*(unsigned long *)pte & PAGE_MASK);
+       if ((unsigned long)va >= (unsigned long)high_memory) {
+               unsigned long pfn; 
+               pfn = pte_pfn(*pte); 
 #ifdef CONFIG_HIGHMEM
-               if ( (phys >> PAGE_SHIFT) < highstart_pfn )
+               if (pfn < highstart_pfn)
 #endif
-                       make_lowmem_page_writable(phys_to_virt(phys));
+                       make_lowmem_page_writable(
+                               phys_to_virt(pfn << PAGE_SHIFT)); 
        }
 }
 
 void make_pages_readonly(void *va, unsigned int nr)
 {
-       while ( nr-- != 0 )
-       {
+       while (nr-- != 0) {
                make_page_readonly(va);
                va = (void *)((unsigned long)va + PAGE_SIZE);
        }
@@ -435,8 +434,7 @@ void make_pages_readonly(void *va, unsigned int nr)
 
 void make_pages_writable(void *va, unsigned int nr)
 {
-       while ( nr-- != 0 )
-       {
+       while (nr-- != 0) {
                make_page_writable(va);
                va = (void *)((unsigned long)va + PAGE_SIZE);
        }
index 091b4e11de35c8a3f457d2ada0519b45971b003d..8579066f30ea7f4e73157c4300b9f95a39849401 100644 (file)
@@ -84,32 +84,37 @@ void show_registers(struct cpu_user_regs *regs)
 
 void show_page_walk(unsigned long addr)
 {
-    unsigned long pfn = read_cr3() >> PAGE_SHIFT;
+    unsigned long mfn = read_cr3() >> PAGE_SHIFT;
     intpte_t *ptab, ent;
+    unsigned long pfn; 
 
     printk("Pagetable walk from %08lx:\n", addr);
 
 #ifdef CONFIG_X86_PAE
-    ptab = map_domain_page(pfn);
-    ent = ptab[l3_table_offset(addr)];
-    printk(" L3 = %"PRIpte"\n", ent);
+    ptab = map_domain_page(mfn);
+    ent  = ptab[l3_table_offset(addr)];
+    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    printk(" L3 = %"PRIpte" %08lx\n", ent, pfn);
     unmap_domain_page(ptab);
     if ( !(ent & _PAGE_PRESENT) )
         return;
-    pfn = ent >> PAGE_SHIFT;
+    mfn = ent >> PAGE_SHIFT;
 #endif
 
-    ptab = map_domain_page(pfn);
-    ent = ptab[l2_table_offset(addr)];
-    printk("  L2 = %"PRIpte" %s\n", ent, (ent & _PAGE_PSE) ? "(PSE)" : "");
+    ptab = map_domain_page(mfn);
+    ent  = ptab[l2_table_offset(addr)];
+    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    printk("  L2 = %"PRIpte" %08lx %s\n", ent, pfn, 
+           (ent & _PAGE_PSE) ? "(PSE)" : "");
     unmap_domain_page(ptab);
     if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
         return;
-    pfn = ent >> PAGE_SHIFT;
+    mfn = ent >> PAGE_SHIFT;
 
     ptab = map_domain_page(ent >> PAGE_SHIFT);
-    ent = ptab[l2_table_offset(addr)];
-    printk("   L1 = %"PRIpte"\n", ent);
+    ent  = ptab[l1_table_offset(addr)];
+    pfn  = machine_to_phys_mapping[(u32)(ent >> PAGE_SHIFT)]; 
+    printk("   L1 = %"PRIpte" %08lx\n", ent, pfn);
     unmap_domain_page(ptab);
 }